package com.example.store.service.impl;

import com.example.store.entity.User;
import com.example.store.mapper.UserMapper;
import com.example.store.service.IUserService;
import com.example.store.service.ex.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.DigestUtils;

import java.util.Date;
import java.util.UUID;
//User的业务实现类
@Service
public class UserServiceImpl implements IUserService {
   @Autowired
    private UserMapper userMapper;


    /**
     * 注册方法
     * @param user 用户数据对象
     */
   @Override
    public void reg(User user) {
        /**
         * 为了检测用户名是否被注册
         * 先获取用户名，在判断
         */
        String username = user.getUsername();
        // 调用持久层的User findByUsername(String username)方法，根据用户名查询用户数据
        User result = userMapper.findByUsername(username);
        // 判断查询结果是否不为null
        if (result != null) {
            // 是：表示用户名已被占用，则抛出UsernameDuplicateException异常
            throw new UsernameDuplicatedException("尝试注册的用户名[" + username +
                    "]已经被占用");
        }

        //执行注册业务功能
        // 创建当前时间对象
        Date now = new Date();
        // 补全数据：加密后的密码
        String salt = UUID.randomUUID().toString().toUpperCase();
        String md5Password = getMd5Password(user.getPassword(), salt);
        user.setPassword(md5Password);
        // 补全数据：盐值
        user.setSalt(salt);
        // 补全数据：isDelete(0)
        user.setIsDelete(0);
        // 补全数据：4项日志属性
        user.setCreatedUser(username);
        user.setCreatedTime(now);
        user.setModifiedUser(username);
        user.setModifiedTime(now);

        // 表示用户名没有被占用，则允许注册
        // 调用持久层Integer insert(User user)方法，执行注册并获取返回值(受影响的行数)
        Integer rows = userMapper.insert(user);
        // 判断受影响的行数是否不为1
        if (rows != 1) {
            // 是：插入数据时出现某种错误，则抛出InsertException异常
            throw new InsertException("添加用户数据出现未知错误，请联系系统管理员");
        }
    }

    /**
     * 执行密码加密
     * @param password 原始密码
     * @param salt 盐值
     * @return 加密后的密文
     */
    private String getMd5Password(String password, String salt) {
        /*
         * 加密规则：
         * 1、无视原始密码的强度
         * 2、使用UUID作为盐值，在原始密码的左右两侧拼接
         * 3、循环加密3次
         */
        for (int i = 0; i < 3; i++) {
            password = DigestUtils.md5DigestAsHex((salt + password +
                    salt).getBytes()).toUpperCase();
        }
        return password;
    }

    /**
     * 登录方法
     *
     * @param username 用户名
     * @param password 密码
     * @return
     */
    @Override
    public User login(String username, String password) {
        /**使用Mapper接口*的findByUsername方法获取用户名，判断是否注册*/
        User name = userMapper.findByUsername(username);
        if (name == null) {
            throw new UsernameNotFoundException("用户名不存在");
        }
        /**判断是否以注销**/
        Integer isDelete = name.getIsDelete();
        if(isDelete == 1){
            throw new UsernameNotFoundException("用户名已注销，请重新注册！");
        }

        /**
         * 获取盐值，对当前密码进行加密
         * 获取数据库的密码用equls进行比较如果一致返回true
         */
        String salt = name.getSalt();
        String md5Password = getMd5Password(password,salt);
        String namePassword = name.getPassword();
        if(!md5Password.equals(namePassword)){
            throw new PasswordError("密码错误！");
        }
        return name;
    }


    /**
     * 修改密码
     * @param uid
     * @param oldPassword
     * @param newPassword
     * @param username
     */
    public void changePassword(Integer uid,String oldPassword,String newPassword, String username){
        User result = userMapper.findByUid(uid);
        Date date = new Date(); 
        if (result == null){
            throw new UsernameNotFoundException("用户不存在！");
        }
        if (result.getIsDelete().equals(1)){
            throw new UsernameNotFoundException("用户已注销，请重新注册！");
        }
        //从结果中查看盐值
        String salt = result.getSalt();

        String oldmd5Password = getMd5Password(oldPassword, salt);
        if (!result.getPassword().contentEquals(oldmd5Password)){
            throw new PasswordError("原密码错误！");
        }
        String newmd5Password = getMd5Password(newPassword, salt);

        //调用UserMapper的方法修改密码
        Integer rows = userMapper.updatePasswordByUid(uid, newmd5Password, username, date);
        if(rows!=1){
            throw new UpdateException("密码修改失败，请联系管理员！");
        }
        System.out.println("修改成功！");;

    }


    @Override
    public User getByUid(Integer uid){

        User result = userMapper.getByUid(uid);
        if (result == null){
            throw new UsernameDuplicatedException("用户不存在！");
        }
        Integer isdelete = result.getIsDelete();
        if (isdelete.equals(1)) {
            throw new UsernameDuplicatedException("用户已被注销，请重新注册！");
        }
        User user = new User();
        user.setUsername(result.getUsername());
        user.setPhone(result.getPhone());
        user.setEmail(result.getEmail());
        user.setGender(result.getGender());


        return user;

    }



    @Override
    public void changeInfo(Integer uid,String username,User user){

        User olduser = userMapper.getByUid(uid);
        if(olduser == null){
            throw new UsernameDuplicatedException("用户不存在！");
        }
        if (olduser.getIsDelete().equals(1)){
            throw new UsernameDuplicatedException("用户已注销，请重新注册!");
        }
        /**
         * 更改用户名，uid，时间
         */

        user.setUid(uid);
        user.setUsername(username);
        user.setModifiedUser(username);
        user.setModifiedTime(new Date());

        Integer newuser = userMapper.updateInfoByUid(user);
        if (newuser != 1){
            throw new UpdateException("更改数据信息失败，请联系管理员！");
        }

    }

}

